import { Mark, mergeAttributes } from "@tiptap/core";
import { Plugin, PluginKey, TextSelection } from "@tiptap/pm/state";
import { commentActions } from "../../store/comment";

export interface CommentOptions {
  HTMLAttributes: Record<string, any>;
}

declare module "@tiptap/core" {
  interface Commands<ReturnType> {
    comment: {
      /**
       * 设置批注
       */
      setComment: (commentId: string, authorId?: string) => ReturnType;
      /**
       * 取消批注标记
       */
      unsetComment: () => ReturnType;
    };
  }
}

export const Comment = Mark.create<CommentOptions>({
  name: "comment",

  // 批注标记不跨越段落边界
  inclusive: false,

  addOptions() {
    return {
      HTMLAttributes: {},
    };
  },

  addAttributes() {
    return {
      commentId: {
        default: null,
        parseHTML: (element) => element.getAttribute("data-comment-id"),
        renderHTML: (attributes) => {
          if (!attributes.commentId) {
            return {};
          }
          return {
            "data-comment-id": attributes.commentId,
          };
        },
      },
      authorId: {
        default: null,
        parseHTML: (element) => element.getAttribute("data-author-id"),
        renderHTML: (attributes) => {
          if (!attributes.authorId) {
            return {};
          }
          return {
            "data-author-id": attributes.authorId,
          };
        },
      },
      resolved: {
        default: false,
        parseHTML: (element) =>
          element.getAttribute("data-resolved") === "true",
        renderHTML: (attributes) => {
          if (!attributes.resolved) {
            return {};
          }
          return {
            "data-resolved": "true",
          };
        },
      },
    };
  },

  parseHTML() {
    return [
      {
        tag: "span[data-comment-id]",
      },
    ];
  },

  renderHTML({ HTMLAttributes }) {
    return [
      "span",
      mergeAttributes(this.options.HTMLAttributes, HTMLAttributes, {
        class: "comment-mark",
      }),
      0,
    ];
  },

  addCommands() {
    return {
      setComment:
        (commentId: string, authorId?: string) =>
        ({ chain }) => {
          return chain().setMark(this.name, { commentId, authorId }).run();
        },
      unsetComment:
        () =>
        ({ chain }) => {
          return chain().unsetMark(this.name).run();
        },
    };
  },

  addKeyboardShortcuts() {
    return {
      // 按 Enter 键换行时，自动移除批注标记
      Enter: ({ editor }) => {
        // 如果当前有批注标记，先移除它
        if (editor.isActive("comment")) {
          editor.commands.unsetMark("comment");
        }
        // 继续执行默认的换行行为
        return false;
      },
      // 按 Shift+Enter 强制换行时，也移除批注标记
      "Shift-Enter": ({ editor }) => {
        if (editor.isActive("comment")) {
          editor.commands.unsetMark("comment");
        }
        return false;
      },
    };
  },

  addProseMirrorPlugins() {
    return [
      new Plugin({
        key: new PluginKey("comment-click-handler"),
        props: {
          handleDOMEvents: {
            // 处理点击事件
            click: (view, event) => {
              const target = event.target as HTMLElement;
              // 查找包含批注标记的元素
              const commentElement = target.closest(
                "[data-comment-id]"
              ) as HTMLElement;

              if (commentElement) {
                const commentId =
                  commentElement.getAttribute("data-comment-id");
                if (commentId) {
                  // 选中批注对应的文本
                  const comment = commentActions.getComment(commentId);
                  if (comment) {
                    const { state, dispatch } = view;
                    const { tr } = state;
                    // 设置选中范围
                    const selection = TextSelection.create(
                      state.doc,
                      comment.position.from,
                      comment.position.to
                    );
                    dispatch(tr.setSelection(selection));
                  }
                  
                  // 打开批注面板（如果关闭）
                  if (!commentActions.isPanelVisible()) {
                    commentActions.togglePanel();
                  }
                  
                  // 设置活动批注
                  commentActions.setActiveComment(commentId);
                  
                  // 阻止默认行为，避免影响编辑器选择
                  event.preventDefault();
                  return true;
                }
              }
              return false;
            },
          },
        },
      }),
    ];
  },
});
